/*
 * Copyright (c)e 2024-2024.Powered by neflibata
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.liuzian.marketserver.service.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liuzian.marketserver.dto.R;
import com.liuzian.marketserver.entity.*;
import com.liuzian.marketserver.mapper.CommodityMapper;
import com.liuzian.marketserver.service.*;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

@Slf4j
@Service
public class CommodityServiceImpl extends ServiceImpl<CommodityMapper, Commodity> implements CommodityService {

    @Lazy
    @Resource
    public UserService userService;

    @Lazy
    @Resource
    public StoreService storeService;

    @Resource
    public ImageService imageService;

    @Resource
    public KindService kindService;

    @Resource
    public MessageService messageService;

    @Override
    public R<List<Commodity>> queryCommodityByName(String name) {
        log.info("get name {}", name);
        LambdaQueryWrapper<Commodity> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(Commodity::getCommodityName, name);
        wrapper.eq(Commodity::getIsAuth, 1);
        wrapper.eq(Commodity::getStatus, 0);
        List<Commodity> commodityList = super.list(wrapper);
        LambdaQueryWrapper<Image> imageLambdaQueryWrapper;
        for (Commodity commodity : commodityList) {
            imageLambdaQueryWrapper = new LambdaQueryWrapper<>();
            imageLambdaQueryWrapper.eq(Image::getGid, commodity.getGid());
            commodity.setImage(imageService.getOne(imageLambdaQueryWrapper));
        }
        return R.success(commodityList);
    }

    @Override
    public R<List<Commodity>> queryCommodityByType(String type) {
        log.info("get type {}", type);
        LambdaQueryWrapper<Commodity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Commodity::getType, type);
        wrapper.like(Commodity::getIsAuth, 1);
        wrapper.eq(Commodity::getStatus, 0);
        List<Commodity> commodityList = super.list(wrapper);
        LambdaQueryWrapper<Image> imageLambdaQueryWrapper;
        for (Commodity commodity : commodityList) {
            imageLambdaQueryWrapper = new LambdaQueryWrapper<>();
            imageLambdaQueryWrapper.eq(Image::getGid, commodity.getGid());
            commodity.setImage(imageService.getOne(imageLambdaQueryWrapper));
        }
        return R.success(commodityList);
    }

    @Override
    public R<Commodity> queryCommodityByGid(Long gid) {
        log.info("get gid {}", gid);
        LambdaQueryWrapper<Commodity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Commodity::getGid, gid);
        Commodity commodity = super.getOne(wrapper);
        LambdaQueryWrapper<Image> imageWrapper = new LambdaQueryWrapper<>();
        imageWrapper.eq(Image::getGid, commodity.getGid());
        imageWrapper.eq(Image::getLabel, 1);
        commodity.setImage(imageService.getOne(imageWrapper));
        LambdaQueryWrapper<Store> storeWrapper = new LambdaQueryWrapper<>();
        storeWrapper.eq(Store::getSid, commodity.getSid());
        commodity.setStore(storeService.getOne(storeWrapper));
        return R.success(commodity);
    }

    @Override
    public R<List<Commodity>> newCommodity() {
        LambdaQueryWrapper<Commodity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Commodity::getIsAuth, 1);
        wrapper.eq(Commodity::getStatus, 0);
        wrapper.orderByDesc(Commodity::getGid);
        wrapper.last("limit 0,5");
        List<Commodity> commodityList = super.list(wrapper);
        LambdaQueryWrapper<Image> imageLambdaQueryWrapper;
        LambdaQueryWrapper<Kind> kindLambdaQueryWrapper;
        for (Commodity commodity : commodityList) {
            imageLambdaQueryWrapper = new LambdaQueryWrapper<>();
            imageLambdaQueryWrapper.eq(Image::getGid, commodity.getGid());
            imageLambdaQueryWrapper.eq(Image::getLabel, 1);
            kindLambdaQueryWrapper = new LambdaQueryWrapper<>();
            kindLambdaQueryWrapper.eq(Kind::getType, commodity.getType());
            commodity.setKind(kindService.getOne(kindLambdaQueryWrapper));
            commodity.setImage(imageService.getOne(imageLambdaQueryWrapper));
        }
        return R.success(commodityList);
    }

    @Override
    public R<List<Commodity>> queryCommodity() {
        LambdaQueryWrapper<Commodity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Commodity::getIsAuth, 1);
        wrapper.eq(Commodity::getStatus, 0);
        List<Commodity> commodityList = super.list(wrapper);
        LambdaQueryWrapper<Image> imageLambdaQueryWrapper;
        LambdaQueryWrapper<Kind> kindLambdaQueryWrapper;
        for (Commodity commodity : commodityList) {
            imageLambdaQueryWrapper = new LambdaQueryWrapper<>();
            imageLambdaQueryWrapper.eq(Image::getGid, commodity.getGid());
            imageLambdaQueryWrapper.eq(Image::getLabel, 1);
            kindLambdaQueryWrapper = new LambdaQueryWrapper<>();
            kindLambdaQueryWrapper.eq(Kind::getType, commodity.getType());
            commodity.setKind(kindService.getOne(kindLambdaQueryWrapper));
            commodity.setImage(imageService.getOne(imageLambdaQueryWrapper));
        }
        if (commodityList.size() <= 15) {
            return R.success(commodityList);
        } else {
            int numToSelect = 15;
            List<Commodity> recommends = new ArrayList<>();
            for (int i = 0; i < numToSelect; i++) {
                Random random = new Random();
                int j = random.nextInt(commodityList.size() - 1);
                Commodity selectCommodity = commodityList.get(j);
                recommends.add(selectCommodity);
                commodityList.remove(selectCommodity);
            }
            return R.success(recommends);
        }
    }

    @Override
    public R<List<Commodity>> queryCommodityByUid(Long uid) {
        LambdaQueryWrapper<Commodity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Commodity::getUid, uid);
        wrapper.eq(Commodity::getIsAuth, 1);
        wrapper.eq(Commodity::getStatus, 0);
        List<Commodity> commodityList = super.list(wrapper);
        LambdaQueryWrapper<Image> imageLambdaQueryWrapper;
        for (Commodity commodity : commodityList) {
            imageLambdaQueryWrapper = new LambdaQueryWrapper<>();
            imageLambdaQueryWrapper.eq(Image::getGid, commodity.getGid());
            commodity.setImage(imageService.getOne(imageLambdaQueryWrapper));
        }
        return R.success(commodityList);
    }

    @Override
    public R<Commodity> addCommodity(Commodity commodity) {
        LambdaQueryWrapper<Store> storeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        storeLambdaQueryWrapper.eq(Store::getUid, commodity.getUid());
        storeLambdaQueryWrapper.eq(Store::getIsAuth, 1);
        Store store = storeService.getOne(storeLambdaQueryWrapper);
        commodity.setCreateTime(new Date());
        commodity.setSid(store.getSid());
        boolean bool = super.save(commodity);
        if (bool) {
            LambdaQueryWrapper<Commodity> commodityLambdaQueryWrapper = new LambdaQueryWrapper<>();
            commodityLambdaQueryWrapper.eq(Commodity::getGid, commodity.getGid());
            Commodity mCommodity = super.getOne(commodityLambdaQueryWrapper);
            Message message = new Message();
            message.setCreateTime(new Date());
            message.setTitle("商品上架申请通知");
            message.setContent("用户" + store.getUid() + "发来了一条商品上架申请");
            message.setUid(Long.valueOf("1420527616925929856"));
            messageService.save(message);
            return R.success(mCommodity);
        } else {
            return R.error("商品添加失败");
        }
    }

    @Override
    public R<List<Commodity>> verifyCommodity() {
        LambdaQueryWrapper<Commodity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Commodity::getIsAuth, 0);
        List<Commodity> commodities = super.list(queryWrapper);
        LambdaQueryWrapper<User> userLambdaQueryWrapper;
        LambdaQueryWrapper<Image> imageLambdaQueryWrapper;
        for (Commodity commodity : commodities) {
            userLambdaQueryWrapper = new LambdaQueryWrapper<>();
            imageLambdaQueryWrapper = new LambdaQueryWrapper<>();
            userLambdaQueryWrapper.eq(User::getUid, commodity.getUid());
            imageLambdaQueryWrapper.eq(Image::getGid, commodity.getGid());
            commodity.setUser(userService.getOne(userLambdaQueryWrapper));
            commodity.setImage(imageService.getOne(imageLambdaQueryWrapper));
        }
        return R.success(commodities);
    }

    @Override
    public R<String> authCommodity(Long gid) {
        LambdaUpdateWrapper<Commodity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Commodity::getGid, gid);
        updateWrapper.set(Commodity::getIsAuth, 1);
        boolean bool = super.update(updateWrapper);
        if (bool) {
            LambdaQueryWrapper<Commodity> commodityLambdaQueryWrapper = new LambdaQueryWrapper<>();
            commodityLambdaQueryWrapper.eq(Commodity::getGid, gid);
            Commodity commodity = super.getOne(commodityLambdaQueryWrapper);
            storeService.updateStoreCount(commodity.getSid());
            Message message = new Message();
            message.setCreateTime(new Date());
            message.setTitle("商品审核结果通知");
            message.setContent("恭喜您，您的商品审核通过，已上架跳蚤市场。");
            message.setUid(commodity.getUid());
            messageService.save(message);
            return R.success("审核通过");
        } else {
            return R.error("修改失败");
        }
    }

    @Override
    public void refuseCommodity(Long gid) {
        LambdaUpdateWrapper<Commodity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Commodity::getGid, gid);
        updateWrapper.set(Commodity::getIsAuth, 2);
        super.update(updateWrapper);
        LambdaQueryWrapper<Commodity> commodityLambdaQueryWrapper = new LambdaQueryWrapper<>();
        commodityLambdaQueryWrapper.eq(Commodity::getGid, gid);
        Commodity commodity = super.getOne(commodityLambdaQueryWrapper);
        Message message = new Message();
        message.setCreateTime(new Date());
        message.setTitle("商品审核结果通知");
        message.setContent("很遗憾，您的商品审核不予通过。");
        message.setUid(commodity.getUid());
        messageService.save(message);
    }

    @Override
    public void browseCommodity(Long gid) {
        LambdaUpdateWrapper<Commodity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Commodity::getGid, gid);
        updateWrapper.setSql("browse = browse + 1");
        super.update(updateWrapper);
    }

    @Override
    public R<String> deleteCommodity(Long gid) {
        LambdaQueryWrapper<Commodity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Commodity::getGid, gid);
        boolean bool = super.remove(queryWrapper);
        if (bool) {
            return R.success("删除商品成功");
        } else {
            return R.error("删除商品失败");
        }
    }

    @Override
    public R<String> pauseCommodity(Long gid) {
        LambdaUpdateWrapper<Commodity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Commodity::getGid, gid);
        updateWrapper.set(Commodity::getStatus, 1);
        boolean bool = super.update(updateWrapper);
        if (bool) {
            return R.success("商品下架成功");
        } else {
            return R.error("商品下架失败");
        }
    }

    @Override
    public Commodity getCommodityByGid(Long gid) {
        LambdaQueryWrapper<Commodity> commodityLambdaQueryWrapper = new LambdaQueryWrapper<>();
        commodityLambdaQueryWrapper.eq(Commodity::getGid, gid);
        return super.getOne(commodityLambdaQueryWrapper);
    }
}
